package cn.org.xiaoweiba.graduationdesign.bookmall.utils;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

/**
 * 和前端进行交互使用的 RSA 工具类
 */
public class RSAUtilInteractiveWithFrontEnd {

    /**
     * 密钥长度为 1024 bit 下,通过公钥生成的密文字符串的长度
     */
    private static final int cipherTextStrLen = 172;

    private RSAUtilInteractiveWithFrontEnd() {}

    /**
     * 使用私钥对密文进行解密(支持长文本)
     * 注意: 此方法只适用于使用和 https://www.yuque.com/u27599042/coding_star/cl4dl599pdmtllw1
     * 中的加密方法逻辑相同的加密处理得到的密文的解密
     *
     * @param privateKey 密钥
     * @param cipherText 密文
     * @return 密文解密后的明文
     */
    public static String decryptByPrivateKey(String privateKey, String cipherText)
            throws NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException,
            InvalidKeySpecException, IOException, BadPaddingException, InvalidKeyException {
        // 获取密文的字符长度
        int cipherTextLen = cipherText.length();
        // 计算分段解密所需的次数 cipherTextStrLen 每段密文的长度
        int decryptCount = cipherTextLen / cipherTextStrLen;
        // 解密后的完整明文
        StringBuilder plainText = new StringBuilder();
        // 对密文进行分段解密
        for (int i = 0; i < decryptCount; i++) {
            // 分段密文距离开始位置的偏移量
            int offSet = i * cipherTextStrLen;
            // 解密当前密文段
            String plainTextSub = RSAUtil.decryptByPrivateStr(privateKey, cipherText.substring(offSet, offSet + cipherTextStrLen));
            // 保存当前密文段解密后的明文
            plainText.append(plainTextSub);
        }
        return plainText.toString();
    }

}
